package org.skydiveapplibrary.repository;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.skydiveapplibrary.data.Database;
import org.skydiveapplibrary.data.Signature;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class SignatureRepository
{
	private Database database;
	
	// signature query
	private static final String GET_SIGNATURE_QUERY =
		"select " +
		"signature._id, " +
		"signature.image, " +
		"signature.license " +
		"from signature " +
		"inner join log_entry_signature on signature._id = log_entry_signature.signature " +
		"where log_entry_signature.log_entry = ?";
	
	public SignatureRepository(Context context)
	{
		database = new Database(context);
	}
	
	public List<Signature> getSignatures()
	{
		List<Signature> signatures = new ArrayList<Signature>();
		
		SQLiteDatabase db = database.getReadableDatabase();
		Cursor cursor = null;
		try
		{
			// perform query
			cursor = db.query(
					Database.SIGNATURE_TABLE,
					Database.SIGNATURE_ALL_COLUMNS,
					null, null, null, null,
					Database.SIGNATURE_LICENSE);
			
			// iterate over results
			while (cursor.moveToNext())
			{
				// create signatures
				Signature signature = createSignature(cursor);
				signatures.add(signature);
			}
		}
		finally
		{
			// close cursor
			if (cursor != null)
			{
				cursor.close();
			}
			// close db
			db.close();
		}
		
		return signatures;
	}
	
	public Signature getSignatureForLogEntry(int logEntryId)
	{
		Signature signature = null;
		
		SQLiteDatabase db = database.getReadableDatabase();
		Cursor cursor = null;
		try
		{
			cursor = db.rawQuery(GET_SIGNATURE_QUERY, new String[] {
					String.valueOf(logEntryId) });
			
			if (cursor.moveToFirst())
			{
				signature = createSignature(cursor);
			}
		}
		finally
		{
			// close cursor
			if (cursor != null)
			{
				cursor.close();
			}
			// close db
			db.close();
		}
		
		return signature;
	}
	
	public void addSignature(Signature signature, List<Integer> logEntryIds)
	{
		SQLiteDatabase db = database.getWritableDatabase();
		// start tx
		db.beginTransaction();
		
		try
		{
			// create signature values
			ContentValues signatureValues = new ContentValues();
			signatureValues.put(Database.SIGNATURE_IMAGE, signature.getImage());
			signatureValues.put(Database.SIGNATURE_LICENSE, signature.getLicense());

			// add signature
			long signatureId = db.insert(Database.SIGNATURE_TABLE, null, signatureValues);
			
			// add join to log entries
			ContentValues joinValues;
			ContentValues utcValues;
			Date currentDate = new Date(System.currentTimeMillis());
			for (int logEntryId: logEntryIds)
			{
				// delete existing signature for log entry
				db.delete(
						Database.LOG_ENTRY_SIGNATURE_TABLE,
						Database.LOG_ENTRY_SIGNATURE_LOG_ENTRY + " = ?",
						new String[] { String.valueOf(logEntryId) });
				
				// create join values
				joinValues = new ContentValues();
				joinValues.put(Database.LOG_ENTRY_SIGNATURE_LOG_ENTRY, logEntryId);
				joinValues.put(Database.LOG_ENTRY_SIGNATURE_SIGNATURE, signatureId);
				
				// add join values
				db.insert(Database.LOG_ENTRY_SIGNATURE_TABLE, null, joinValues);
				
				// update log entry last signature utc
				utcValues = new ContentValues();
				utcValues.put(Database.LOG_ENTRY_LAST_SIGNATURE_UTC, Database.dateTimeToString(currentDate));
				db.update(
						Database.LOG_ENTRY_TABLE,
						utcValues,
						Database.LOG_ENTRY_ID + " = ?",
						new String[] { String.valueOf(logEntryId) });
			}
			
			// set tx success
			db.setTransactionSuccessful();
		}
		finally
		{
			// end tx
			db.endTransaction();
			// close db
			db.close();
		}
	}
	
	private Signature createSignature(Cursor cursor)
	{
		Signature signature = new Signature();
		signature.setId(Database.getInteger(cursor, Database.SIGNATURE_ID));
		signature.setImage(Database.getBinaryData(cursor, Database.SIGNATURE_IMAGE));
		signature.setLicense(Database.getString(cursor, Database.SIGNATURE_LICENSE));
		return signature;
	}
	
	public String[] getSignatureLicenses()
	{
		String[] licenses = new String[] {};
		
		SQLiteDatabase db = database.getReadableDatabase();
		Cursor cursor = null;
		try
		{
			// perform query
			cursor = db.query(
					Database.SIGNATURE_TABLE,
					new String[] {Database.SIGNATURE_LICENSE},
					null, null, Database.SIGNATURE_LICENSE, null,
					Database.SIGNATURE_LICENSE);
			
			licenses = new String[cursor.getCount()];
			
			// iterate over results
			int i = 0;
			while (cursor.moveToNext())
			{
				licenses[i] = Database.getString(cursor, Database.SIGNATURE_LICENSE);
				i++;
			}
		}
		finally
		{
			// close cursor
			if (cursor != null)
			{
				cursor.close();
			}
			// close db
			db.close();
		}
		
		return licenses;
	}
}
